package com.rockcent.mall.lib.repository;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.rockcent.common.common.PageResult;
import com.rockcent.common.common.SQLObjectDoing;
import com.rockcent.common.common.SQLPageDoing;
import com.rockcent.common.domain.enumclass.Whether;
import com.rockcent.common.utils.RDateUtils;
import com.rockcent.mall.lib.domain.enumclass.CustomerFundFlowTransactionType;
import com.rockcent.mall.lib.domain.enumclass.PaymentMethod;
import com.rockcent.mall.lib.dto.CustomerFundFlowDto;
import com.rockcent.mall.lib.dto.StatisticDto;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;


/**
 * Created by DK on 16/11/21.
 */
@Repository
public class CustomerFundFlowRepositoryImpl implements CustomerFundFlowRepositoryCustom{

    private static final Logger log = LoggerFactory.getLogger(CustomerFundRepositoryImpl.class);

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public PageResult<CustomerFundFlowDto> findMallCustomerFundInfo(Long customerId, String mallOrderNum, String transactionType, String paymentMethod, String beginDate, String endDate, Long mallId, PageResult pageResult) {
        SQLPageDoing<CustomerFundFlowDto> doing = (sql, fields, params, typeReferenceMap) -> {
            sql.append("select %s from customer_fund_flow cff where 1=1");
            if (customerId != null) {
                sql.append(" and cff.customer_id = :customerId");
                params.put("customerId", customerId);
            }

            if (StringUtils.isNotBlank(mallOrderNum)) {
                sql.append(" and cff.mall_order_num = :mallOrderNum");
                params.put("mallOrderNum", mallOrderNum);
            }

            if (PaymentMethod.ALL != PaymentMethod.valueOf(paymentMethod)) {
                sql.append(" and cff.payment_method = :paymentMethod");
                params.put("paymentMethod", paymentMethod);
            }

            if (CustomerFundFlowTransactionType.ALL != CustomerFundFlowTransactionType.valueOf(transactionType)) {
                sql.append(" and cff.transaction_type = :transactionType");
                params.put("transactionType", transactionType);
            } else {
                sql.append(" and cff.transaction_type != 'ORDER_RECHARGE'");
                params.put("transactionType", transactionType);
            }

            if (StringUtils.isNotBlank(beginDate) && StringUtils.isNotBlank(endDate)) {
                sql.append(" AND cff.date_created < :endDate AND cff.date_created > :beginDate");
                params.put("beginDate", RDateUtils.beforeDateStr(beginDate, 0));
                params.put("endDate", RDateUtils.afterDateStr(endDate, 1));
            }

            sql.append(" and cff.mall_id = :mallId");
            params.put("mallId", mallId);
            sql.append(" order by cff.date_created desc");
            fields.append("cff.*");
        };
        return doing.go(pageResult, CustomerFundFlowDto.class, objectMapper, jdbcTemplate, log);
    }
    @Override
    public PageResult<CustomerFundFlowDto> findCustomerIdPage(Long customerId,Long mallId,Whether no,PageResult pageResult){
        SQLPageDoing<CustomerFundFlowDto> doing = (sql, fields, params, typeReferenceMap) -> {
            sql.append("select %s from customer_fund_flow cff where 1=1 and cff.mall_id = :mallId and cff.customer_id = :customerId and cff.is_delete = :isDelete and cff.transaction_type <> \"ORDER_RECHARGE\" and cff.operation_amount > 0 order by cff.date_created desc ");
            fields.append("cff.*");
            params.put("customerId",customerId);
            params.put("isDelete",Whether.NO.toString());
            params.put("mallId",mallId);
        };
        return doing.go(pageResult, CustomerFundFlowDto.class, objectMapper, jdbcTemplate, log);
    }
    @Override
    public StatisticDto findStatisticSum(Long customerId){
        SQLObjectDoing<StatisticDto> doing = (sql, fields, params, typeReferenceMap) -> {
            sql.append("SELECT SUM(operation_amount) AS statistic_sum FROM customer_fund_flow WHERE customer_id = :customerId AND transaction_type = \"SHARE_FEE\" ");
            params.put("customerId",customerId);
        };
        return doing.go(StatisticDto.class, jdbcTemplate, log, objectMapper);
    }
    @Override
    public Double findMonthlyIncome(Long customerId, String firstDate, String lastDate){
        SQLObjectDoing<Double> doing = (sql, fields, params, typeReferenceMap) -> {
            sql.append("SELECT SUM(operation_amount)  FROM customer_fund_flow WHERE customer_id = :customerId AND transaction_type = \"SHARE_FEE\" ");
            sql.append(" AND (date_created BETWEEN :firstDate AND :lastDate)  ");
            params.put("customerId",customerId);
            params.put("firstDate",firstDate);
            params.put("lastDate",lastDate);
        };
        return doing.go(Double.class, jdbcTemplate, log, objectMapper);
    }
}
